package com.zktravel.service.template;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.odianyun.util.BeanUtils;
import com.odianyun.util.db.query.PageVO;
import com.zktravel.constants.ProductConstant;
import com.zktravel.constants.ShopConstant;
import com.zktravel.core.exception.VisibleException;
import com.zktravel.enums.CodeEnum;
import com.zktravel.mapper.PlBrandMapper;
import com.zktravel.mapper.PlCategoryMapper;
import com.zktravel.mapper.PlProductMapper;
import com.zktravel.model.dto.brand.BrandItem;
import com.zktravel.model.dto.category.CategoryGroup;
import com.zktravel.model.dto.product.PlProductDTO;
import com.zktravel.model.dto.product.ProductItem2B;
import com.zktravel.model.dto.product.ProductItem2C;
import com.zktravel.model.dto.template.Template;
import com.zktravel.model.po.PlCategory;
import com.zktravel.model.po.Shop;
import com.zktravel.model.vo.brand.PlBrandVO;
import com.zktravel.model.vo.category.PlCategoryVO;
import com.zktravel.model.vo.product.PdQueryParams;
import com.zktravel.model.vo.product.PlProductVO;
import com.zktravel.service.BaseServiceImpl;
import com.zktravel.util.HttpUtils;
import com.zktravel.util.JsonHelper;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class TemplateServiceImpl extends BaseServiceImpl implements TemplateService {
    /**
     * 调用 go 接口用
     */
    @Value("#{configProperties['access.domain']}")
    private String domain;
    @Resource
    private PlBrandMapper plBrandMapper;
    @Resource
    private PlProductMapper plProductMapper;
    @Resource
    private PlCategoryMapper plCategoryMapper;
    @Resource
    private PlCategoryMapper PlCategoryMapper;

    /**
     * B端
     * 店铺管理-店铺模版
     */
    @Override
    public Map<String, Object> getShopTemplate2B(Long shopId, Long userId) {
        // 返回前端数据
        Map<String, Object> rstMap = Maps.newHashMap();
        // 1. 已选择的模板
        List<Template> tplList = this.getSelectTplList(shopId, userId);
        rstMap.put("template", tplList);

        // 2. 未选择的模板 B端需要
        // B端已选择的模板类型
        List<Integer> idList = Lists.newArrayList();
        for (Template item : tplList) {
            idList.add(item.getType());
        }

        List<Object> unList = this.getUnSelectTplList(idList);
        rstMap.put("unSelect", unList);

        return rstMap;
    }

    /**
     * @param shopId B 端商品id
     */
    @Override
    public Map<String, Object> getShopTemplate2C(Long shopId) {
        // 返回前端数据
        Map<String, Object> rstMap = Maps.newHashMap();
        // 1. 已选择的模板
        // 选择的模版列表
        List<Template> rstList = new ArrayList<>();
        // 获取店主保存的模板
        List<Template> tplList = this.getShopTemplate(shopId);

        Shop shopResult = this.getShopInfo(shopId);
        for (Template tpl : tplList) {
            tpl = this.fillProductForTemplate2C(shopId, shopResult.getUserId(), tpl);
            rstList.add(tpl);
        }
        rstMap.put("template", rstList);

        return rstMap;
    }

    /**
     * B端店铺已选择的模板
     */
    private List<Template> getSelectTplList(Long shopId, Long userId) {
        // 选择的模版列表
        List<Template> rstList = new ArrayList<>();
        // 获取店主保存的模板
        List<Template> tplList = this.getShopTemplate(shopId);
        Boolean isVip = this.getUser(userId).isVip();
        for (Template tpl : tplList) {
            tpl = this.fillProductForTemplate2B(shopId, userId, isVip, tpl);
            rstList.add(tpl);
        }

        return rstList;
    }

    private List<Object> getBrandList(Long shopId, Integer maxNum) {
        List<Object> oList = new ArrayList<>();

        List<PlBrandVO> list = this.plBrandMapper.list(shopId, 0, maxNum);
        for (PlBrandVO bTpl : list) {
            Object bItem = BeanUtils.copyProperties(bTpl, BrandItem.class);
            oList.add(bItem);
        }

        return oList;
    }

    /**
     * 查询该模板的商品列表
     *
     * @param shopId 店铺ID
     * @param uId    用户ID
     * @param tpl    店铺模板
     */
    private Template fillProductForTemplate2B(Long shopId, Long uId, Boolean isVip, Template tpl) {
        Integer catId = tpl.getType();
        List<Object> oList = new ArrayList<>();
        if (catId.equals(ShopConstant.TYPE_MINE)) {
            tpl.setList(this.getMediaList(uId));
            return tpl;
        }
        // 获取大牌推荐
        if (catId.equals(ShopConstant.TYPE_BRAND)) {
            tpl.setList(this.getBrandList(shopId, tpl.getNum()));
            return tpl;
        }

        PdQueryParams qry = new PdQueryParams();
        qry.setTopType(tpl.getType());
        qry.setShopId(shopId);
        qry.setCategoryId(catId.longValue());
        qry.setOrderBy(ProductConstant.ORDERBY_SELL_NUM); // 销量排序
        qry.setPageNo(1);
        qry.setPageSize(tpl.getNum());
        qry.setVip(isVip);
        // 欧洲必买 | 新品上架
        if (catId.equals(ShopConstant.TYPE_EUROPE_BUY) || catId.equals(ShopConstant.TYPE_NEW_PRODUCT)) {
            qry.setCategoryId(-100L); // 无效分类，检索时会忽略该参数
        }
        PageVO<ProductItem2B> list = this.getProductList(qry);
        for (ProductItem2B item : list.getList()) {
            Object sProd = BeanUtils.copyProperties(item, ProductItem2B.class);
            oList.add(sProd);
        }
        tpl.setList(oList);

        return tpl;
    }

    /**
     * 查询该模板的商品列表
     *
     * @param shopId 店铺ID
     * @param uId    用户ID
     * @param tpl    店铺模板
     */
    private Template fillProductForTemplate2C(Long shopId, Long uId, Template tpl) {
        Integer catId = tpl.getType();
        List<Object> oList = new ArrayList<>();
        if (catId.equals(ShopConstant.TYPE_MINE)) {
            tpl.setList(this.getMediaList(uId));
            return tpl;
        }
        // 获取大牌推荐
        if (catId.equals(ShopConstant.TYPE_BRAND)) {
            tpl.setList(this.getBrandList(shopId, tpl.getNum()));
            return tpl;
        }

        PdQueryParams qry = new PdQueryParams();
        qry.setTopType(tpl.getType());
        qry.setShopId(shopId);
        qry.setCategoryId(catId.longValue());
        qry.setOrderBy(ProductConstant.ORDERBY_SELL_NUM); // 销量排序
        qry.setPageNo(1);
        qry.setPageSize(tpl.getNum());
        // 欧洲必买 | 新品上架
        if (catId.equals(ShopConstant.TYPE_EUROPE_BUY) || catId.equals(ShopConstant.TYPE_NEW_PRODUCT)) {
            qry.setCategoryId(-100L); // 无效分类，检索时会忽略该参数
        }
        if (catId.equals(ShopConstant.TYPE_NEW_PRODUCT)) {
            qry.setOrderBy(null); // 销量排序
        }
        PageVO<ProductItem2C> list = this.getProductList2C(qry);
        for (ProductItem2C item : list.getList()) {
            Object sProd = BeanUtils.copyProperties(item, ProductItem2C.class);
            oList.add(sProd);
        }
        tpl.setList(oList);

        return tpl;
    }

    /**
     * B端店铺未选的模板
     *
     * @param idList 已经选择的ID列表
     */
    private List<Object> getUnSelectTplList(List<Integer> idList) {
        List<Object> unList = Lists.newArrayList();
        List<PlCategoryVO> unSelectList = this.plCategoryMapper.getUnSelectList(idList);
        for (PlCategoryVO item : unSelectList) {
            Map<String, Object> dat = Maps.newHashMap();
            dat.put("code", item.getId());
            dat.put("num", item.getTplNum());
            dat.put("name", item.getName());
            dat.put("image", item.getImage());
            unList.add(dat);
        }

        return unList;
    }

    /**
     * 获取笔记素材
     *
     * @param uId 用户id
     * @return 笔记素材数据
     */
    private List<Object> getMediaList(Long uId) {
        List<Object> list = new ArrayList<>();
        if (null == uId) {
            return list;
        }

        Map<String, String> parameters = ImmutableMap.of("tId", uId.toString());
        String json = JsonHelper.bean2Json(parameters);
        String dataResult = HttpUtils.sendPostJsonRequest(this.domain + "/tr-media/cli-note/home-list", json);

        JSONObject jo = JSONObject.parseObject(dataResult);
        if ("0".equals(jo.get("code")) || jo.get("code").equals(0)) {
            list = JsonHelper.json2List(jo.get("list").toString(), Object.class);
        }

        return list;
    }

    /**
     * C 端商品检索
     *
     * @param qry 检索参数
     */
    @Override
    public PageVO<ProductItem2C> getProductList2C(PdQueryParams qry) {
        List<ProductItem2C> rstList = new ArrayList<>();

        if (ShopConstant.TYPE_EUROPE_BUY != qry.getTopType() && ShopConstant.TYPE_NEW_PRODUCT != qry.getTopType() && null == qry.getCategoryId()) {
            qry.setCategoryId(qry.getTopType().longValue());
        }
        List<PlProductVO> list = this.plProductMapper.getProductList(qry);
        Long cnt = this.plProductMapper.getProductCount(qry);

        for (PlProductVO item : list) {
            ProductItem2C pd = new ProductItem2C();
            // 基础信息
            pd.setId(item.getId());
            pd.setName(item.getName());
            pd.setMainImageUrl(item.getMainImageUrl());
            if (item.getSort() > 0 && item.getSort() < 999) {
                pd.setTop(1);
            }
            // 售价
            pd.setCounterPrice(item.getCounterPrice());// TODO 此处价格调高后有bug
            pd.setSellPrice(item.getSellPrice());
            // 库存与销量
            pd.setStockNum(item.getStockNum());
            pd.setStockArea(item.getStockArea());
            pd.setSellNum(item.getSellNum());
            pd.setBriefIntroduction(item.getBriefIntroduction());

            rstList.add(pd);
        }
        return new PageVO<>(cnt, rstList);
    }

    /**
     * B 端商品检索
     *
     * @param qry 检索参数
     */
    @Override
    public PageVO<ProductItem2B> getProductList(PdQueryParams qry) {
        List<ProductItem2B> rstList = new ArrayList<>();

        if (ShopConstant.TYPE_EUROPE_BUY != qry.getTopType() && ShopConstant.TYPE_NEW_PRODUCT != qry.getTopType() && null == qry.getCategoryId()) {
            qry.setCategoryId(qry.getTopType().longValue());
        }
        List<PlProductVO> list = this.plProductMapper.getProductList(qry);
        Long cnt = this.plProductMapper.getProductCount(qry);

        for (PlProductVO item : list) {
            ProductItem2B pd = new ProductItem2B();
            // 基础信息
            pd.setId(item.getId());
            pd.setName(item.getName());
            pd.setMainImageUrl(item.getMainImageUrl());
            if (item.getSort() > 0 && item.getSort() < 999) {
                pd.setTop(1);
            }
            // 售价
            pd.setCounterPrice(item.getCounterPrice());
            pd.setSellPrice(item.getSellPrice());
            pd.setMarketPrice(item.getMarketPrice());
            pd.setProfitAmt(item.getProfitAmt());
            // VIP售价
            if (null != qry.getVip() && qry.getVip() && null != item.getMarketPriceVip() && !item.getMarketPrice().equals(item.getMarketPriceVip())) {
                pd.setHasVip(true);
                pd.setMarketPriceVip(item.getMarketPriceVip());
                pd.setProfitAmtVip(item.getProfitAmtVip());
            }
            // 库存与销量
            pd.setStockNum(item.getStockNum());
            pd.setStockArea(item.getStockArea());
            pd.setSellNum(item.getSellNum());

            rstList.add(pd);
        }

        return new PageVO<>(cnt, rstList);
    }

    /**
     * 获取类型类目品牌列表
     */
    @Override
    public List<CategoryGroup> getCategoryGroup(Integer catId, Long shopId, Long userId) {
        // category_id list
        // category map
        List<PlCategoryVO> catList = this.plCategoryMapper.listAll();
        List<Long> catIdList = new ArrayList<>();
        Map<Long, PlCategoryVO> catMap = new HashMap<>();
        for (PlCategoryVO catItem : catList) {
            catMap.put(catItem.getId(), catItem);
            catIdList.add(catItem.getId());
        }

        PlProductDTO prodDTO = new PlProductDTO();
        prodDTO.setShopId(shopId);
        if (ShopConstant.TYPE_EUROPE_BUY == catId || ShopConstant.TYPE_NEW_PRODUCT == catId) {
            // 如果是欧洲必买或新品上架，显示所有类目和品牌
            prodDTO.setCategoryIdList(catIdList);
        } else {
            // 如果是其他类型，根据类型获取对应类目，根据类目查询品牌
            prodDTO.setCategoryIdList(Lists.newArrayList(catId.longValue()));
        }

        List<BrandItem> allBrand = new ArrayList<>();
        Map<Long, Integer> brandFlag = new HashMap<>();

        // sql 查询
        List<PlProductVO> prodList = this.plProductMapper.listBrandCate(prodDTO);
        List<CategoryGroup> grpList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(prodList)) {
            // 整理每个category 下的brand
            Map<Long, List<BrandItem>> brandMap = new HashMap<>();
            prodList.forEach(item -> {
                List<BrandItem> tempList = brandMap.get(item.getCategoryId());
                if (CollectionUtils.isEmpty(tempList)) {
                    tempList = new ArrayList<>();
                    brandMap.put(item.getCategoryId(), tempList);
                }

                // 只插入有效数据
                if (null == item.getBrandId() || null == item.getBrandName()) {
                    return;
                }

                BrandItem bItem = new BrandItem();
                bItem.setId(item.getBrandId());
                bItem.setName(item.getBrandName());
                tempList.add(bItem);

                //整理所有的brand
                if (!brandFlag.containsKey(item.getBrandId())) {
                    allBrand.add(bItem);
                    brandFlag.put(item.getBrandId(), 1);
                }
            });

            for (Map.Entry<Long, List<BrandItem>> map : brandMap.entrySet()) {
                PlCategoryVO cat = catMap.get(map.getKey());
                if (null != cat) {
                    CategoryGroup catGroup = new CategoryGroup();
                    catGroup.setCategoryId(map.getKey());
                    catGroup.setCategoryName(cat.getName());
                    catGroup.setBrandList(map.getValue());
                    grpList.add(catGroup);
                }
            }
        }
        // 全部分类
        if (ShopConstant.TYPE_EUROPE_BUY == catId || ShopConstant.TYPE_NEW_PRODUCT == catId) {
            // 如果是欧洲必买或新品上架，显示所有类目和品牌
            CategoryGroup catGroup = new CategoryGroup();
            catGroup.setCategoryId((long) -1);
            catGroup.setCategoryName("全部");
            catGroup.setBrandList(allBrand);
            grpList.add(0, catGroup);
        }

        return grpList;
    }

    /**
     * 获取用户商铺模板
     */
    @Override
    public List<Template> getShopTemplate(Long shopId) {
        Shop shopResult = this.getShopInfo(shopId);
        if (null == shopResult) {
            return new ArrayList<>();
        }
        String tplStr = shopResult.getTemplate();
        List<Template> tplList = JsonHelper.json2List(tplStr, Template.class);

        List<Template> list = new ArrayList<>();
        if (null != tplList) {
            list = tplList.stream().filter(
                    item -> null != item.getNum() && null != item.getType()
            ).collect(Collectors.toList());
        }
        if (CollectionUtils.isEmpty(list)) {
            list = Lists.newArrayList(
                    new Template(ShopConstant.TYPE_BRAND, ProductConstant.PAGESIZE_LIMIT_4),
                    new Template(ShopConstant.TYPE_EUROPE_BUY, ProductConstant.PAGESIZE_LIMIT_4),
                    new Template(ShopConstant.TYPE_NEW_PRODUCT, ProductConstant.PAGESIZE_LIMIT_6),
                    new Template(ShopConstant.TYPE_MINE, ProductConstant.PAGESIZE_LIMIT_4)
            );
        }

        for (int i = 0; i < list.size(); i++) {
            Template item = list.get(i);
            PlCategory qryT = new PlCategory();
            qryT.setId(item.getType().longValue());
            PlCategory rstT = this.PlCategoryMapper.selectOne(qryT);
            if (null != rstT) {
                item.setName(rstT.getName());
                item.setImage(rstT.getImage());
            }
            list.set(i, item);
        }

        return list;
    }

    // 更改用户模板
    @Override
    public void updateShopTemplate(List<Template> tplList, Long shopId) {
        for (Template temp : tplList) {
            if (null == temp.getType()) {
                throw new VisibleException(CodeEnum.PRODUCT_TOP_TYPE_NOT_NULL);
            }
            if (null == temp.getNum()) {
                throw new VisibleException(CodeEnum.NUM_NOT_NULL);
            }
        }

        String template = JsonHelper.bean2Json(tplList);

        Shop shop = new Shop();
        shop.setId(shopId);
        shop.setTemplate(template);

        this.shopMapper.updateTemplate(shop);
    }
}
